home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C ++ / Applications / Venus 3.5 / SimpleWindow.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-10  |  20.3 KB  |  615 lines  |  [TEXT/CWIE]

  1. /*
  2.  ***********************************************************************
  3.  *
  4.  *                    Simple Window Class
  5.  *    A generic simple window that can be dragged around the screen
  6.  *        and closed by clicking a "go-away" button
  7.  * No other events are handled, redefine the event handler if necessary.
  8.  *        
  9.  *
  10.  ***********************************************************************
  11.  */
  12.  
  13. #include "image.h"
  14. #include "window.h"
  15. #include <Palettes.h>
  16. #include "EventHandlers.h"
  17.  
  18. /*
  19.  *----------------------------------------------------------------------
  20.  *                Service functions
  21.  */
  22.  
  23.                 // Getting a bounding rectangle of an image
  24. ScreenRect::ScreenRect(const IMAGE& image)
  25. {
  26.   left = top = 0;
  27.   right = image.q_ncols();
  28.   bottom = image.q_nrows();
  29. }
  30.  
  31. #if 0
  32.  
  33.                 // Create a rectangle of given height/width
  34.                 // positioned at the origin
  35. ScreenRect::ScreenRect(const rowcol& heightwidth)
  36. {
  37.   left = top = 0;
  38.   bottom = heightwidth.row();
  39.   right  = heightwidth.col();
  40. }
  41.  
  42.                     // Create a rectangle of given height/width
  43.                     // positioned at a given point
  44. ScreenRect::ScreenRect(const rowcol& origin, const rowcol& heightwidth)
  45. {
  46.   top  = origin.row();
  47.   left = origin.col();
  48.   bottom = top+heightwidth.row();
  49.   right  = left+heightwidth.col();
  50. }
  51. #endif
  52.  
  53.  
  54.                     // Shifting a rectangle by the same amount
  55.                     // in X and Y
  56. ScreenRect& ScreenRect::operator += (const int offset)
  57.   top += offset; bottom += offset; left += offset; right += offset;
  58.   return *this;
  59. }
  60.  
  61.  
  62.                     // Print what rectangle is this
  63. void ScreenRect::print(const char * title) const
  64. {
  65.   alert("Rectangle %s (%d,%d) - (%d,%d)",title,top,left,bottom,right);
  66. }
  67.  
  68.  
  69. #if 0
  70. /*
  71.  *----------------------------------------------------------------------
  72.  *                 Primitive Window creators/destructors
  73.  */
  74.  
  75.                         // This is a protected constructor. Normally
  76.                         // objects XVTBasicWindow are created as a part
  77.                         // of a derived class
  78. XVTBasicWindow::XVTBasicWindow(void)
  79. {
  80.   Not_canceled = FALSE;
  81.   this_window = NULL_WIN;
  82. }
  83.  
  84.                         // Destroy the window if it hasn't been destroyed
  85.                         // already
  86. XVTBasicWindow::~XVTBasicWindow(void)
  87. {
  88.   if( this_window != 0 )
  89.     close_window(this_window);
  90. }
  91.  
  92.                         // Close the window
  93. void XVTBasicWindow::cancel(void)
  94. {
  95.   Not_canceled = FALSE;
  96.   if( this_window != 0 )
  97.     close_window(this_window);
  98. }
  99.  
  100. /*
  101.  *----------------------------------------------------------------------
  102.  *                   Basic event dispatching/handling
  103.  */
  104.  
  105.                         // A universal event handler: does almost nothing
  106.                         // but watches creation and destruction of windows
  107.                         // (to tell when there are no windows to watch)
  108.                         // For any other tasks, it calls the handler of
  109.                         // a particular window
  110. int XVTBasicWindow::no_opened_windows = 0;
  111. long XVTBasicWindow::universal_handler(WINDOW win, EVENT *ep)
  112.  
  113. {
  114.   XVTBasicWindow& the_window = *(XVTBasicWindow *)get_app_data(win);
  115.  
  116.   if( ep->type == E_CREATE )
  117.     no_opened_windows++, the_window.this_window = win;
  118.  
  119.   the_window.handler(*ep);
  120.  
  121.                                 // XVT would destroy the window after this
  122.                                 // event
  123.   if( ep->type == E_DESTROY )
  124.     no_opened_windows--, the_window.this_window = 0;
  125.  
  126.   return 0;
  127. }
  128.  
  129.                                 // Serve the windows until all get closed
  130. void XVTBasicWindow::serve_to_death(void)
  131. {
  132.   while( no_opened_windows>0 )
  133.     process_events();
  134. }
  135.  
  136.  
  137.                         // Event handler for a particular window
  138.                         // Finally, a handler which really does smth
  139.                         // specific
  140. void XVTBasicWindow::handler(EVENT event)
  141. {
  142.   switch(event.type)
  143.   {
  144.     case E_CREATE:
  145.          if( !initialize() )
  146.            cancel();
  147.          break;
  148.   }
  149. }
  150.  
  151. /*
  152.  *----------------------------------------------------------------------
  153.  *                              Window creators
  154.  *
  155.  * Note, event processing may start *before* the create_* functions return!
  156.  * So, if initialize() or event handlers, etc rely on some data that are
  157.  * going to be initialized *after* create_* function, you're in trouble!
  158.  * It's better to call create() function the last thing in the constructor,
  159.  * or even not to call at all (call it separetely later) to allow derived
  160.  * classes initialize properly!
  161.  *
  162.  */
  163. #endif
  164.  
  165. /*
  166.  *----------------------------------------------------------------------
  167.  *                              Window creators
  168.  */
  169.  
  170.                 // Create a color window of the specified size and title
  171.                 // Note, the upper left corner of 'rect' must
  172.                 // NOT be (0,0)!
  173.                 // The window is created hidden; call init() to finish
  174.                 // the processing and show the window
  175.                                 // Kepp in mind that the window is hidden right after
  176.                                 // the construction
  177.                                 // Call init() to fincish the construction and reveal it
  178. ScreenWindow::ScreenWindow(ScreenRect rect, const char * title)
  179.   : private_palette(nil)
  180. {
  181.   const int window_offset = 100;        // Cannot be 0 or small!
  182.   this_window = NewCWindow(nil,rect += window_offset,(Pstr)title,
  183.                FALSE,noGrowDocProc,
  184.                (WindowPtr)(-1),TRUE,(long)this);
  185.   assert( this_window != 0 );
  186.   SetPort(this_window);
  187.   SelectWindow(this_window);
  188. }
  189.  
  190.                 // Create a color window from a resource template
  191. ScreenWindow::ScreenWindow(const short resource_id)
  192.     : private_palette(nil)
  193. {
  194.   this_window = GetNewCWindow(resource_id,nil,(WindowPtr)(-1));
  195.   SetWRefCon(this_window,(long)this);
  196.   assert( this_window != 0 );
  197.   SetPort(this_window);
  198.   SelectWindow(this_window);
  199. }
  200.  
  201.  
  202.             // I wouldn't've needed this is destructor had been really virtual. Right now,
  203.             // CW 6.0 accepts attribute virtual for the destructor, but doesn't override
  204.             // destructors as it does for virtual functions. Oh, well, another kludge
  205.  
  206.                             // Close the window and clean up the rubble
  207. void ScreenWindow::destroy_it(void)
  208. {
  209.   assert( this_window != nil );
  210.   if( private_palette != nil )            // If there was a private palette allocated
  211.   {
  212.     if( GetPalette(this_window) == private_palette )
  213.       NSetPalette(this_window,nil,pmNoUpdates);    // if it was bound to a window, break the bond
  214.     DisposePalette(private_palette);
  215.     private_palette = nil;
  216.   }
  217.   DisposeWindow(this_window);
  218.   this_window = nil;
  219. }
  220.  
  221. /*
  222.  *----------------------------------------------------------------------
  223.  *                           Basic Even Handling
  224.  */
  225.  
  226.                 // The top-level event dispatcher
  227.                 // Returns FALSE when the window is to be destroyed
  228.                 // and thus won't need any further events
  229. Boolean ScreenWindow::handle_event(const EventRecord& the_event)
  230. {
  231.   switch( the_event.what )
  232.   {
  233.     case mouseDown:
  234.          {
  235.            WindowPtr    wp;
  236.            short        windowPart = FindWindow(the_event.where, &wp);
  237.            return handle_mouse_down(the_event,wp,windowPart);
  238.          }
  239.             
  240.     case updateEvt:
  241.          if( this_window == (WindowPtr)the_event.message )
  242.            update();
  243.          break;
  244.  
  245.     case keyDown:
  246.     case autoKey:
  247.            return handle_key_down(the_event);
  248.                         
  249.     case EventHandler::mykind:
  250.          return handle_my_event(the_event);
  251.          
  252.     case activateEvt:
  253.          if( this_window == (WindowPtr)the_event.message )
  254.            if( the_event.modifiers & 0x01 )
  255.              SetPort(this_window);
  256.          break;
  257.   }
  258.   return TRUE;
  259. }
  260.  
  261.                 // Handle "mouse-down" events
  262.                 // Returns FALSE if the user clicked within the
  263.                 // go-away region of our window. Otherwise,
  264.                 // returns TRUE
  265.                 // Handles dragging if necessary and system clicks
  266. Boolean ScreenWindow::handle_mouse_down
  267.     (const EventRecord& the_event, WindowPtr where_window, short window_part)
  268. {
  269.   switch( window_part )
  270.   {
  271.     case inSysWindow: 
  272.          SystemClick(&the_event, where_window);
  273.      break;
  274.         
  275.     case inMenuBar:
  276.          break;                // Don't handle it yet
  277.  
  278.     case inContent:
  279.          break;
  280.           
  281.     case inDrag:
  282.          if( this_window == where_window )
  283.            DragWindow(this_window,the_event.where,&qd.screenBits.bounds);
  284.          break;
  285.                       
  286.     case inGoAway:
  287.          return !TrackGoAway(where_window, the_event.where);
  288.   }
  289.   return TRUE;
  290. }
  291.  
  292.                 // Handles key_down & auto_key events. Return FALSE
  293.                 // if the window is to be closed down
  294. Boolean ScreenWindow::handle_key_down(const EventRecord& the_event)
  295. {
  296.   return FALSE;                // Any key kills the application, sorry
  297. }
  298.  
  299.  
  300.                 // Handles null events, when nothing happens for some
  301.                 // time. Return FALSE when it's time to die
  302. Boolean ScreenWindow::handle_null_event(const long event_time)
  303. {
  304.   return TRUE;                            // Keep going
  305. }
  306.  
  307.  
  308.                 // Handles my private events... It's up to the user...
  309. Boolean ScreenWindow::handle_my_event(const EventRecord& the_event)
  310. {
  311.   EventHandler::put_back(the_event);
  312.   return FALSE;
  313. }
  314.  
  315.  
  316.  
  317.             // Private window parts
  318.                 // Handle an update event - redraw the window
  319.                 // A virtual function draw() is called to do
  320.                 // the actual redrawing
  321. void ScreenWindow::update(void)
  322. {
  323.   SetNewGrafPtr((GrafPtr)this_window);
  324.   BeginUpdate(this_window);
  325.   draw();
  326.   EndUpdate(this_window);
  327. }
  328.  
  329.                 // Make the entire window being redrawn
  330. void ScreenWindow::refresh(void)
  331. {
  332.   InvalRect(&this_window->portRect);            
  333. }
  334.  
  335.             // First step of negotiating color environment for the window:
  336.             // Create a palette based on a given colormap, associate it
  337.             // with the window, and have the PaletteManager negotiate
  338.             // with the graphic device(s) and update the hardware tables
  339.             // accordingly
  340. void ScreenWindow::set_private_palette(const CTabHandle clut)
  341. {
  342.   assert( clut != nil && *clut != nil );
  343.  
  344.   private_palette = NewPalette((**clut).ctSize,clut,pmTolerant+pmExplicit,0);
  345.   assert( private_palette != nil );
  346.   SetPalette(this_window,private_palette,TRUE);
  347.   do_well( QDError() );
  348.   ActivatePalette(this_window);    
  349.   do_well( QDError() );
  350. }
  351.  
  352. /*
  353.  *----------------------------------------------------------------------
  354.  *                            Color Lookup Table
  355.  */
  356.  
  357.                                         // Load from a 'clut' resource
  358. CLUTable::CLUTable(const short clut_id)
  359.     : handle(GetCTable(clut_id)), my_own_handle(true)
  360. {
  361.   assert( handle != 0 );
  362.   (**handle).ctFlags |= 0x4000;            // A Flag that tells QD that this CLUT and a palette
  363.                                           // are to be synchronized. That is, 
  364.                                           // (**handle).ctTable[i].value is understood as index
  365.                                           // in the current window palette (rather than a pixel
  366.                                           // value). That means, no time would be wasted
  367.                                           // for matching of colors when moving offscreen to onscreen
  368.                                           // See IM, Advanced Color Imaging, Chap 1,
  369.                                           // Palette Manager, p. 1-36
  370. }
  371.  
  372.                         // Deep copy of the other clut, which may be null
  373.                         // (in the latter case, this clut is also emptied)
  374.                         // Because it's a deep copy, it copies even in a CTabHandle
  375.                         // we don't own
  376.                         // Still, we keep the old CLUT's ctFlags
  377. void CLUTable::deep_copy_from(const CLUTable& other_clut)
  378. {
  379.   if( &other_clut == this  || other_clut.handle == handle )
  380.     return;
  381.     
  382.   if( other_clut.q_null() )            // Assigning a null CLUT empties this one too
  383.   {
  384.     if(my_own_handle)
  385.      DisposeCTable(handle);
  386.     handle = nil;
  387.     my_own_handle = false;
  388.     return;
  389.   }
  390.   
  391.   if( handle == nil )
  392.   {
  393.     my_own_handle = true;
  394.     handle = other_clut.handle;
  395.     do_well( HandToHand(&(Handle)handle) );        // Clone the other_clut's handle
  396.   }
  397.   else
  398.   {
  399.     const short old_ctFlags = (**handle).ctFlags;
  400.     const int other_size = GetHandleSize((Handle)other_clut.handle);
  401.     assert( other_size > 4 );
  402.     if( (**handle).ctSize != (**other_clut.handle).ctSize )
  403.       SetHandleSize((Handle)handle,other_size);
  404.     HLock((Handle)handle); HLock((Handle)other_clut.handle);
  405.     memcpy(*handle, *other_clut.handle,other_size);
  406.     HUnlock((Handle)handle); HUnlock((Handle)other_clut.handle);
  407.     (**handle).ctFlags = old_ctFlags;
  408.    }
  409.   CTabChanged(handle);
  410. }
  411.  
  412.                                 // Dump the whole contents of the CLUT
  413. void CLUTable::dump(const char title []) const
  414. {
  415.   if( handle == nil )
  416.   {
  417.     message("\nColor Lookup Table '%s' does not actually exist\n",title);
  418.     return;
  419.   }
  420.   
  421.   message("\nColor Lookup Table '%s' with %s handle",title,
  422.               my_own_handle ? "own" : "borrowed");
  423.               
  424.   message("\nseed %d, flags 0x%0x",(**handle).ctSeed,(**handle).ctFlags);
  425.   message("\nThe table has %d entries, They are:",(**handle).ctSize);
  426.   for(register int i=0; i<(**handle).ctSize; i++)
  427.     {
  428.       const ColorSpec& color_spec = (**handle).ctTable[i];
  429.       message("\n\t%d -> %d:%d:%d",color_spec.value,
  430.               color_spec.rgb.red,color_spec.rgb.green,color_spec.rgb.blue);
  431.      }
  432.   message("\n\n");
  433. }
  434.  
  435.                                 // Tell briefly about this CLUT
  436. void CLUTable::info(const char title []) const
  437. {
  438.   if( handle == nil )
  439.   {
  440.     message("\nColor Lookup Table '%s' does not actually exist\n",title);
  441.     return;
  442.   }
  443.   message("\nColor Lookup Table '%s' with %s handle",title,
  444.               my_own_handle ? "own" : "borrowed");
  445.               
  446.   message("\nseed %d, flags 0x%0x, %d entries\n",
  447.       (**handle).ctSeed,(**handle).ctFlags,(**handle).ctSize);
  448. }
  449.  
  450. /*
  451.  *----------------------------------------------------------------------
  452.  *                An off-screen pixel buffer for faster drawing
  453.  */
  454.  
  455.                     // Allocate the buffer for offscreen
  456.                     // drawing and load a CLUT (if clut_id != 0)
  457. OffScreenBuffer::OffScreenBuffer(ScreenRect rect, const CLUTable& clut)
  458.     : graf_world(nil)
  459. {
  460.   do_well( NewGWorld(&graf_world,8,rect, clut.q_null() ? nil : (CTabHandle)clut,nil,0) );
  461.   assert( graf_world != nil );
  462.                                 // BTW, CLUT has been copied, so 'clut' can be disposed of 
  463.  
  464.                     // Get hold of the offscreen pixmap
  465.   pixmap = GetGWorldPixMap(graf_world);            // and make sure it looks like
  466.   assert( pixmap != nil && *pixmap != nil );    // we can use it
  467.  
  468.   assert( (**pixmap).cmpCount == 1 );            // We have a color table index
  469.   assert( !PixMap32Bit(pixmap) );
  470.  
  471.   _height = abs((**pixmap).bounds.top - (**pixmap).bounds.bottom);
  472.   _width  = abs((**pixmap).bounds.right - (**pixmap).bounds.left);
  473.   _bytes_per_row = (**pixmap).rowBytes & 0x7fff;
  474.  
  475.   assert( _height > 0 && _height < 10000 );         // Just to play safe
  476.   assert( _width > 0 && _width <= _bytes_per_row );    
  477. }
  478.  
  479.                     // Dispose of the offscreen buffer
  480. OffScreenBuffer::~OffScreenBuffer(void)
  481. {
  482.   assert( graf_world != nil );
  483.   DisposeGWorld(graf_world);
  484.   graf_world = nil;
  485.   pixmap = nil;
  486.   _height = _width = _bytes_per_row = 0;
  487. }
  488.  
  489.  
  490.  
  491.                 // Actual drawing - moving the picture from the
  492.                 // offscreen grafworld to the onscreen one, to the current port.
  493.                 // Remember to set a device to that of the offscreen
  494.                 // grafworld before CopyBits (in order to get grafworld's color table and 
  495.                 // inverse color table to be used): see IM, Palette Manager
  496.                 // Also note, if a window we're going to draw on is partly/completely
  497.                 // obscured, then the visRgn, the visible region of the on-screen window,
  498.                 // is *not* a window rectangle. When we make the offscreen grafworld the
  499.                 // current grafport for CopyBits, CopyBits has no way of knowing then that
  500.                 // the true destination region may not be the whole where_rect at all. To make
  501.                 // CopyBits aware of the fact that the onscreen window maybe abscured, we
  502.                 // pass the visRgn of the onscreen window as a clipping region to CopyBits.
  503.                 // In that case CopyBits performs clipping just as if the onscreen window
  504.                 // where the current grafport.
  505.                 // Note, to be really precise, we ought to pass CopyBits() an intersection of
  506.                 // onscreen grafport's visRgn and clipRgn. Well, we take a shortcut here:
  507.                 // normally clipRgn is set to be the whole screen. Moreover, visRgn is clipped
  508.                 // already not only to the unobscured part of the window, but to the update
  509.                 // region as well. So using visRgn only should suffice....
  510.                 // Also make sure that the onscreen window has a palette roughly corresponding
  511.                 // to the CLUT of the grafworld (otherwise colors would be screwed up)
  512.                 // One can use a palette resource 0 to be used as a default palette for
  513.                 // dialogs/windows within the task
  514.                 
  515.                 // Note there is a different way to force color translation when drawing a picture
  516.                 // (seems to work better in 68k universe). One needs to create a grafworld, and
  517.                 // and draw on it within OpenPicture()...ClosePicture(). Then one can draw
  518.                 // thus recorded picture on the current window. The colors seem to get translated
  519.                 // correctly, and one doesn't need to worry about clipping, etc (as in the method
  520.                 // way explained above). One can use this technique to force 24->8 color
  521.                 // translation (with dithering) if the grafworld was created as 24-bit.
  522.  
  523.                 // Also note a GetSubTable() ColorManager's function: it apparently allows
  524.                 // one to perform the necessary color translation/selection once, and
  525.                 // use only indices later!
  526.                 
  527. void OffScreenBuffer::draw(const Rect& where_rect, const Rect& from_rect)
  528. {
  529. //  const BitMap * where_pixmap = &qd.thePort->portBits;    // see below
  530.   CGrafPtr old_port;
  531.   GDHandle old_gdevice;
  532.   GetGWorld(&old_port,&old_gdevice);
  533.   const RgnHandle where_visible_region = old_port->visRgn;
  534.   SetGWorld((CGrafPtr)graf_world,nil);
  535.                                                   // The following line is actually the same as
  536.                                                   // the one commented at the very top. However,
  537.                                                   // thePort stuff doesn't work under OpenDoc, but
  538.                                                   // the following line does.
  539.   const BitMap * where_pixmap = &((GrafPtr)old_port)->portBits;
  540.   //!!!Set_NewGrafWorld((GWorldPtr)graf_world);    // Doesn't work: CW disposes of the object too early
  541.   assert( LockPixels(pixmap) );
  542.   CopyBits((const BitMap *)*pixmap, where_pixmap, &from_rect, &where_rect, /*ditherCopy*/ srcCopy, where_visible_region);
  543.   SetGWorld(old_port,old_gdevice);
  544.   UnlockPixels(pixmap);
  545. }
  546.  
  547.                                         // Clear the buffer
  548. void OffScreenBuffer::clear(void)
  549. {
  550.   GrafPtr old_port = set_this_grafptr();
  551.   EraseRect(&(**pixmap).bounds);
  552.   SetPort(old_port);
  553. }
  554.  
  555.                                   // Optimize the OffScreen buffer for the faster
  556.                                   // display on a given color device
  557.                                   // That means, if the g_device and the offscreen world
  558.                                   // are compatible (have the same depth) we "disable"
  559.                                   // the color translation in CopyBits from this gworld
  560.                                   // to an on-screen GWorld. We assume that gdevice color
  561.                                   // tables are already set up appropriately (by the
  562.                                   // palette manager, for example)
  563. Boolean OffScreenBuffer::optimize_color_worlds(const GDHandle g_device)
  564. {
  565.   const PixMapHandle on_screen_pixmap = (**g_device).gdPMap;
  566.   if( (**on_screen_pixmap).pixelSize != (**pixmap).pixelSize )
  567.     return FALSE;                // GWorlds are obviously very different...
  568.   const CTabHandle on_screen_clut = (**on_screen_pixmap).pmTable;
  569.   if( on_screen_clut == nil )
  570.     return FALSE;
  571.   CTabHandle off_screen_clut = (**pixmap).pmTable;
  572.   assert( off_screen_clut != nil );
  573.   if( (**on_screen_clut).ctSize < (**off_screen_clut).ctSize )
  574.     return FALSE;                // Color translation (reduction) is obviously necessary
  575.   (**off_screen_clut).ctSeed = (**on_screen_clut).ctSeed;    // That'll make CopyBits faster!
  576.   return TRUE;
  577. }
  578.  
  579.  
  580.                                       // Brute imposing of our color world on the
  581.                                       // g_device: settip up its colortables by force
  582.                                       // Chances are it would screw colors of all other
  583.                                       // windows; but if we're the only window on the screen
  584.                                       // or we don't care
  585.                                       // If this imposition succeeds (the function returns
  586.                                       // TRUE), our grafworld when blitted on screen would
  587.                                       // certainly look at its (color) best
  588. Boolean OffScreenBuffer::impose_on_gdevice(GDHandle g_device)
  589. {
  590.   const PixMapHandle on_screen_pixmap = (**g_device).gdPMap;
  591.   if( (**g_device).gdType == fixedType )
  592.     return FALSE;                // CLUT on this device can't be changed
  593.                                 // what about a direct device? Should we try to impose on it too?
  594.                                 
  595.   if( (**on_screen_pixmap).pixelSize != (**pixmap).pixelSize )
  596.     return FALSE;                // GWorlds are obviously very different...
  597.   CTabHandle on_screen_clut = (**on_screen_pixmap).pmTable;
  598.   if( on_screen_clut == nil )
  599.     return FALSE;
  600.   CTabHandle off_screen_clut = (**pixmap).pmTable;
  601.   assert( off_screen_clut != nil );
  602.                                   // Build a ReqListReq for a 256-entry CLUT
  603.   short req_list_buffer[256+1];
  604.   ReqListRec * const req_list = (ReqListRec *)req_list_buffer;
  605.   req_list->reqLSize = sizeof(req_list_buffer)/sizeof(req_list_buffer[0]) - 1 - 1; // number of entries - 1
  606.   for(register int i=0; i<=req_list->reqLSize; i++)
  607.     req_list->reqLData[i] = i;                // means move all CLUT entries
  608.   //Debugger();
  609.   RestoreEntries(off_screen_clut,on_screen_clut,req_list);    // Foist our color table
  610.   do_well( QDError() );
  611.   (**off_screen_clut).ctSeed = (**on_screen_clut).ctSeed;    // Make the tables look as if there are the same
  612.   return TRUE;
  613. }
  614.